<template>
  <div>
    <div class="snpm-title">{{$t('配置SNMP之前需要开启自身防护SNMP开关!')}}</div>
    <div class="system-snpm" :style="lang === 'zh' ?'max-width: 1200px;':'max-width: 1400px;'">
      <el-divider content-position="left">{{ $t("SNMP") }}</el-divider>
      <el-form ref="ruleForm" :disabled="info.status==='disable'" :model="info[info.version]" :label-width="lang === 'zh' ? '110px' : '250px'" label-position="left" inline style="width: 100%">
        <el-row>
          <!-- <el-col :span="24">
            <el-form-item :label="$t('SNMP')" prop="status">
              <el-switch :width="lang === 'zh' ? 60 : 70" v-model="info.status" id="system-snpm-status" class="switch" active-color="#009966" inactive-color="#CCCCCC" active-value="enable" inactive-value="disable" :active-text="$t('启用')" :inactive-text="$t('停用')" @change="handleSwitchChange" />
            </el-form-item>
          </el-col> -->
          <div>
            <el-col :span="24">
              <el-form>
                <el-form-item :label="$t('版本')" prop="version">
                  <el-radio-group v-model="info.version" @change="handleRadio">
                    <el-radio v-for="item in versionList" :label="item.value" :key="item.value" :id="`system-snpm-${item.value}`">{{ item.label }}</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-form>
            </el-col>
            <el-col :span="24" v-if="['v1', 'v2c'].includes(info.version)">
              <el-form-item prop="community" :label="$t('SNMP只读团体名')" :rules="rules.community">
                <el-input v-emoji v-model.trim="info[info.version].community" ref="community" size="small" id="system-snmp-community">
                </el-input>
              </el-form-item>
            </el-col>
            <el-col :span="24" v-if="['v3'].includes(info.version)">
              <el-form-item :label="$t('安全用户名')" prop="user" :rules="rules.user">
                <el-input v-emoji v-model.trim="info[info.version].user" size="small" id="system-snmp-user">
                </el-input>
              </el-form-item>
            </el-col>
            <el-col :span="24" v-if="['v3'].includes(info.version)">
              <el-form-item :label="$t('认证方式')" prop="auth_type" :rules="rules.selectRequired">
                <el-select size="small" v-model="info[info.version].auth_type">
                  <el-option v-for="item in auth_type_options" :key="item.value" :label="item.label" :value="item.value" :id="`system-snmp-${item.value}`">
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item :label="$t('认证密码')" prop="auth_password" :rules="rules.password">
                <el-input v-emoji v-model.trim="info[info.version].auth_password" ref="addr" size="small" id="system-snmp-auth_password">
                </el-input>
              </el-form-item>
            </el-col>

            <el-col :span="24" v-if="['v3'].includes(info.version)">
              <el-form-item :label="$t('加密方式')" prop="priv_type" :rules="rules.selectRequired">
                <el-select size="small" v-model="info[info.version].priv_type">
                  <el-option v-for="item in priv_type_options" :key="item.value" :label="item.label" :value="item.value" :id="`system-snmp-${item.value}`">
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item :label="$t('加密密码')" prop="priv_password" :rules="rules.password">
                <el-input v-emoji v-model.trim="info[info.version].priv_password" ref="addr" size="small" id="system-snmp-priv_password">
                </el-input>
              </el-form-item>
            </el-col>
            <el-col :span="24" v-for="(item, index) in info[info.version].trap" :key="`item-${index}`">
              <el-form-item :label="$t('Trap接收地址')" :prop="`trap.${index}.host`" :rules="rules.trapRequired(item, index, 'host')">
                <el-input v-emoji v-model.trim="item.host" ref="host" size="small" :id="`system-snmp-host-${(item, index)}`">
                </el-input>
              </el-form-item>
              <el-form-item :label="$t('端口')" :prop="`trap.${index}.port`" label-width="40px" :rules="rules.trapRequired(item, index, 'port')">
                <el-input v-emoji v-model.trim="item.port" ref="port" size="small" style="width: 120px" :id="`system-snmp-port-${index}`">
                </el-input>
              </el-form-item>
              <el-form-item :label="$t('安全名')" :prop="`trap.${index}.name`" :label-width="lang === 'zh' ? '50px':'100px'" :rules="rules.trapRequired(item, index, 'name')">
                <el-input v-emoji v-model.trim="item.name" ref="name" size="small" :id="`system-snmp-name-${index}`">
                </el-input>
              </el-form-item>
              <el-form-item :label="$t('引擎ID')" :prop="`trap.${index}.engineid`" :label-width="lang === 'zh' ? '50px':'100px'" v-if="['v3'].includes(info.version)" :rules="rules.erengineid">
                <el-input v-emoji v-model.trim="item.engineid" ref="engineid" size="small" :id="`system-snmp-engineid-${index}`">
                </el-input>
              </el-form-item>
              <el-form-item>
                <i v-if="index===0 && info[info.version].trap.length<5" class="el-icon-circle-plus-outline system-snpm-add" id="system-snpm-add" @click="handleAdd(item)"></i>
                <i v-else-if="index===0 && info[info.version].trap.length==5"></i>
                <i v-else class="el-icon-remove-outline system-snpm-del" id="system-snpm-del" @click="handleDel(item, index)"></i>
              </el-form-item>
            </el-col>
          </div>
        </el-row>
      </el-form>

      <div class="btn-group">
        <el-button type="success" :disabled="info.status==='disable'" @click="handleSubmit" id="system-snmp-submit">{{
        $t("应用配置")
      }}</el-button>
        <el-button type="danger" :disabled="info.status==='disable'" @click="handleClear" id="system-snmp-clear">{{
        $t("清空配置")
      }}</el-button>
      </div>
      <warningTools :dialogVisible="dialogVisible" :msg="msg" @visibleSubmit="visibleSubmit" />
    </div>
  </div>
</template>
<script>
import { getSnmp, clearSnmp, editSnmp, snmpSwitch } from "@/api/system/snmp";
import warningTools from "@/components/warningTools/index";
export default {
  name: "Snmp",
  components: {
    warningTools,
  },
  computed: {
    trapTemp() {
      return JSON.parse(JSON.stringify(this.info[this.info.version].trap));
    },
  },
  data() {
    const validaterRequired = (rule, value, callback) => {
      if (!String(value).trim()) {
        callback(new Error(this.$t('不能为空')));
      } else {
        callback();
      }
    };
    // 团体名
    const validaterCommunity = (rule, value, callback) => {
      if (!String(value).trim()) {
        callback(new Error(this.$t('不能为空')));
      } else if (value.length < 6 || value.length > 31) {
        callback(new Error(this.$t('团体名长度为6-31')));
      } else {
        callback();
      }
    };
    // 安全用户名
    const validaterUser = (rule, value, callback) => {
      if (!String(value).trim()) {
        callback(new Error(this.$t('不能为空')));
      } else if (value.length < 1 || value.length > 31) {
        callback(new Error(this.$t('安全用户名长度为1-31')));
      } else {
        callback();
      }
    };
    // 密码
    const validaterPassword = (rule, value, callback) => {
      if (!String(value).trim()) {
        callback(new Error(this.$t('不能为空')));
      } else if (value.length < 8 || value.length > 31) {
        callback(new Error(this.$t('密码长度为8-31')));
      } else {
        callback();
      }
    };
    // 引擎ID
    const validatErengineid = (rule, value, callback) => {
      if (!String(value).trim()) {
        callback();
      } else if (value.length < 10 || value.length > 64){
          return callback(new Error(this.$t('引擎id长度为10-64')));
        } else {
        callback();
      }
    };
    const validaterRequiredTemp = (rule, value, callback, v, index, type) => {
      console.log("index", index);
      console.log("v", v);
      const arr = [];
      for (const k in v) {
        if (k !== "id") {
          arr.push(v[k]);
        }
      }
      const flagEvery = arr.every((item) => item);
      const flag = arr.some((item) => item);
      if (value) {
        if (type === "host") {
          return callback();
        }
        if (type === "port") {
          if (isNaN(Number(value)))
            return callback(new Error(this.$t('只能输入数字')));
          if (Number(value) < 1 || Number(value) > 65535)
            return callback(new Error(this.$t('端口范围为1-65535')));
        }
        if (type === "name") {
          if (value.length < 6 || value.length > 31)
            return callback(new Error(this.$t('安全名长度为6-31')));
        }
        if (type === "engineid") {
          if (value.length < 10 || value.length > 64)
            return callback(new Error(this.$t('引擎id长度为10-64')));
        }
        if (flagEvery) {
          return callback();
        }
      } else {
        if (flag) return callback(new Error(this.$t('不能为空')));
      }
      return callback();
    };
    return {
      dialogVisible: false,
      msg: "",
      lang: this.$i18n.locale,
      versionList: [
        {
          value: "v1",
          label: "V1",
        },
        {
          value: "v2c",
          label: "V2c",
        },
        {
          value: "v3",
          label: "V3",
        },
      ],
      auth_type_options: [
        {
          value: "MD5",
          label: "MD5",
        },
        {
          value: "SHA",
          label: "SHA",
        },
      ],
      priv_type_options: [
        {
          value: "AES",
          label: "AES",
        },
        {
          value: "DES",
          label: "DES",
        },
      ],
      infoTemp: {}, // 拷贝的临时数据
      infoInit: {},
      info: {
        status: "",
        version: "v3",
        port: "",
        v1: {
          community: "",
          del: [],
          trap: [
            {
              host: "",
              port: "",
              name: "",
            },
          ],
        },
        v2c: {
          community: "",
          del: [],
          trap: [
            {
              host: "",
              port: "",
              name: "",
            },
          ],
        },
        v3: {
          auth_type: "",
          priv_password: "",
          priv_type: "",
          priv_password: "",
          user: "",
          del: [],
          trap: [
            {
              host: "",
              port: "",
              name: "",
              engineid: "",
            },
          ],
        },
      },
      rules: {
        community: [{ trigger: "blur", validator: validaterCommunity }],
        user: [{ trigger: "blur", validator: validaterUser }],
        password: [{ trigger: "blur", validator: validaterPassword }],
        erengineid: [{ trigger: "blur", validator: validatErengineid }],
        trapRequired: (item, index, type) => [
          {
            trigger: "blur",
            validator: (rule, value, callback) =>
              validaterRequiredTemp(rule, value, callback, item, index, type),
          },
        ],
        selectRequired: [{ trigger: "change", validator: validaterRequired }],
      },
    };
  },
  mounted() {
    this.infoInit = JSON.parse(JSON.stringify(this.info));
    this.init();
  },
  methods: {
    // 新增
    handleAdd(item) {
      console.log(item);
      const itemTemp = JSON.parse(JSON.stringify(item));
      for (const k in itemTemp) {
        itemTemp[k] = "";
      }
      delete itemTemp.id;
      console.log(itemTemp);
      this.info[this.info.version].trap.push(itemTemp);
    },
    // 删除
    handleDel(item, index) {
      if (item.id) {
        this.info[this.info.version].del.push({
          id: item.id,
        });
      }
      this.info[this.info.version].trap.splice(index, 1);
    },
    // 版本
    handleRadio() {
      this.$refs.ruleForm.clearValidate();
    },
    // 初始数据
    async init() {
      try {
        const resp = await getSnmp();
        const { status, info } = resp;
        const { port, v1, v2c, v3 } = info[0];
        if (status === 0) {
          console.log(" this.info", this.info);
          this.info = {
            ...this.info,
            port,
            status: info[0].status,
            v1: {
              del: [],
              community: v1.community || "",
              trap: (v1.trap && v1.trap.length && v1.trap) || this.info.v1.trap,
            },
            v2c: {
              del: [],
              community: v2c.community || "",
              trap:
                (v2c.trap && v2c.trap.length && v2c.trap) || this.info.v2c.trap,
            },
            v3: {
              del: [],
              user: v3.user || "",
              auth_type: v3.auth_type || "",
              auth_password: v3.auth_password || "",
              priv_type: v3.priv_type || "",
              priv_password: v3.priv_password || "",
              trap: (v3.trap && v3.trap.length && v3.trap) || this.info.v3.trap,
            },
          };
          console.log("this.info", this.info);
          this.infoTemp = JSON.parse(JSON.stringify(this.info));
        }
        console.log("resp", resp);
      } catch (err) {
        console.log(err);
      }
    },
    reset() {
      const infoInit = JSON.parse(JSON.stringify(this.infoInit));
      infoInit.version = this.info.version;
      this.info = infoInit;
      this.init();
    },
    async editSnmp(params) {
      try {
        const resp = await editSnmp(params);
        console.log("resp", resp);
        const { status } = resp;
        if (status === 0) {
          this.$messages.success(this.$t('设置成功！'));
        }
        for (const item of ["v1", "v2c", "v3"]) {
          this.info[item].del = [];
        }
        this.reset();
      } catch (err) {
        console.log(err);
        if (err.status === -1000) {
          this.dialogVisible = true;
          this.msg = err.msg || "";
          this.reset();
        }
      }
    },
    visibleSubmit() {
      this.dialogVisible = false;
      this.msg = "";
    },
    async handleSwitchChange() {
      try {
        const { status, port } = this.info;
          const params = {
            status,
            port,
          };
          await snmpSwitch(params);
      } catch (err) {
        this.info.status = this.info.status === "enable" ? "disable" : "enable";
        console.log(err);
      }
    },
    handleSubmit() {
      this.$refs.ruleForm.validate((valid) => {
        if (valid) {
          const { status, version, port } = this.info;
          const info = JSON.parse(JSON.stringify(this.info[this.info.version]));
          const trap = info.trap;
          delete info.trap;
          delete info.del;
          const params = {
            status,
            version,
            port,
            info: JSON.stringify(info),
          };

          const isObjectPropertiesExceptAAllTrue = (obj) => {
            // 确保传入的是一个对象  
            if (typeof obj !== 'object' || obj === null) {  
                return false;  
            }
            for(const key in obj) {
              if(key !== 'engineid' && !obj[key]) {
                return false;
              }
            }
            return true;
          }
          let add = trap.filter((item) => !item.id);
          let edit = [];
          const del = this.info[this.info.version].del; // 删除的数据
          // 当前数据
          const infoTrap = this.info[this.info.version].trap.filter(
            (item) => item.id
          );
          // 拷贝的数据
          const infoTempTrap = this.infoTemp[this.info.version].trap.filter(
            (item) => item.id
          );
          // 编辑的数据
          for (const item of infoTrap) {
            for (const itemTemp of infoTempTrap) {
              if (
                item.id === itemTemp.id &&
                JSON.stringify(item) !== JSON.stringify(itemTemp)
              ) {
                edit.push(item);
              }
            }
          }
          for (let i = add.length - 1; i >= 0; i--) {
            const flag = isObjectPropertiesExceptAAllTrue(add[i]);
            if (!flag) {
              add.splice(i, 1);
            }
          }
          for (let i = edit.length - 1; i >= 0; i--) {
            const flag = isObjectPropertiesExceptAAllTrue(edit[i]);
            if (!flag) {
              del.push({
                id: edit[i].id,
              });
              edit.splice(i, 1);
            }
          }
          params.add = JSON.stringify(add);
          params.edit = JSON.stringify(edit);
          params.del = JSON.stringify(del);
          console.log("params", params);
          this.editSnmp(params);
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    handleClear() {
      try {
        this.$confirm(this.$t('您是否要清空配置?'), this.$t('提示'), {
          closeOnClickModal: false,
          confirmButtonText: this.$t('确定'),
          cancelButtonText: this.$t('取消'),
          confirmButtonClass: "confirmButton",
          cancelButtonClass: "confirmCancelButton",
          type: "warning",
        }).then(async () => {
          const { version } = this.info;
          const params = {
            version,
          };
          const resp = await clearSnmp(params);
          const { status, msg } = resp;
          if (status === 0) {
            this.$messages.success(this.$t(msg));
            this.reset();
          }
        });
      } catch (err) {
        console.log(err);
      }
    },
  },
};
</script>
<style lang="less" scoped>
.system-snpm {
  margin: 0 auto;
  padding-top: 1px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  .el-divider__text {
    font-size: 18px;
    font-weight: 600;
  }
  .el-divider {
    margin: 40px 0 30px;
  }
  .system-snpm-add,
  .system-snpm-del {
    font-size: 18px;
    cursor: pointer;
  }
  /deep/ .el-select,
  .el-input {
    width: 230px;
  }
}
.snpm-title {
  text-align: right;
  color: red;
}
</style>
